home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / comp / iku.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-05  |  7.3 KB  |  280 lines

  1. // copying
  2.     // Copyright (C) 1991 David Stoutamire (daves@alpha.ces.cwru.edu)
  3.     //
  4.     // This program is free software; you can redistribute it and/or modify
  5.     // it under the terms of the GNU General Public License as published by
  6.     // the Free Software Foundation, version 2.
  7.     // 
  8.     // This program is distributed in the hope that it will be useful,
  9.     // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.     // GNU General Public License for more details.
  12.     // 
  13.     // You should have received a copy of the GNU General Public License
  14.     // along with this program (file "COPYING"); if not, write to the Free
  15.     // Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  
  17. #define MAINFILE
  18. #include "iku.h"
  19.  
  20. void foreachfile(String files, Stringfuncptr f) {
  21.     // Call f for each file expanded by string files.
  22.     // "allgames" gets translated to value of allgames, and
  23.     // "forever" does allgames over and over.
  24.     int forever=0;
  25.     if (files=="allgames")
  26.         files=allgames;
  27.     else if (files=="forever") {
  28.         forever=1;
  29.         files=allgames;
  30.         }
  31.     do { 
  32.         #ifndef IRIX
  33.         FILE* pd=popen((char*)("ls -1 "+files),"r");   
  34.         File ff(pd);
  35.         int count=0;
  36.         while (!ff.eof()) {
  37.             char *cp;
  38.             ff.gets(&cp);
  39.             if (ff.eof()&&count==0) 
  40.                 fatal("Could not find file(s): "+files);
  41.         #else /* IRIX */
  42.         FILE* pd=popen((char*)("cd games; ls "+files),"r");   
  43.         int count=0;
  44.         while (!feof(pd)) {
  45.             char cp[1000];
  46.             if (fgets(cp,1000,pd)==NULL) {
  47.                 if (count==0)
  48.                     fatal("Could not find file(s): "+files);
  49.                 else
  50.                     break;
  51.                 }
  52.             cp[strlen(cp)-1]='\0';
  53.         #endif /* IRIX */
  54.             count++;
  55.             String s(cp);
  56.             if (s!="") 
  57.                 f(s);
  58.             #ifdef IRIX
  59.             free(cp);
  60.             #endif /* IRIX */
  61.             }
  62.         pclose(pd);
  63.         } while (forever);
  64.     }
  65.  
  66. static Opponent *optostudy;    // for communication with dostudy
  67. void dostudy(String& f) {
  68.     // Study game f: call learn for each move in the game
  69.     // global "optostudy" is the opponent which this affects
  70.     Game g(f);
  71.     if (evalfile!="nofile")
  72.         system((char*)("echo EVENT >"+evalfile));
  73.     for (int i=0;i<g.nummoves;i++) {
  74.         optostudy->study(g.snapshot(i),g.moves[i]);
  75.         }
  76.     if (dolearn)
  77.     optostudy->docheckpt();     // sync with disk after each game
  78.     }
  79.  
  80. const int syma(int a,int b,int i) {
  81.     // compute a' for symmetry i given a and b as offsets
  82.     switch (i) {
  83.         case 0:
  84.             return(a);
  85.         case 1:
  86.             return(a);
  87.         case 2:
  88.             return(-a);
  89.         case 3:
  90.             return(-a);
  91.         case 4:
  92.             return(b);
  93.         case 5:
  94.             return(b);
  95.         case 6:
  96.             return(-b);
  97.         case 7:
  98.             return(-b);
  99.         default:
  100.             fatal("Error in syma switch.");
  101.         }
  102.     }
  103.  
  104. const int symb(int a,int b,int i) {
  105.     // compute b' for symmetry i given a and b as offsets
  106.     switch (i) {
  107.         case 0:
  108.             return(b);
  109.         case 1:
  110.             return(-b);
  111.         case 2:
  112.             return(-b);
  113.         case 3:
  114.             return(b);
  115.         case 4:
  116.             return(a);
  117.         case 5:
  118.             return(-a);
  119.         case 6:
  120.             return(-a);
  121.         case 7:
  122.             return(a);
  123.         default:
  124.             fatal("Error in symb switch.");
  125.         }
  126.     }
  127.  
  128. String nextarg() {
  129.     // returns next argument from command line; fatal if no more
  130.     global_argv++;
  131.     global_argc--;
  132.     if (global_argc>0)
  133.         return(String(*global_argv));
  134.     else
  135.         fatal("Not enough command line args.");
  136.     }
  137.  
  138. void verify(String& s) {
  139.      // verify that the file s is internally consistent
  140.      cout << "Verifying " << s << "... ";
  141.      cout.flush();
  142.      Game* g=new Game(s);
  143.      delete g;
  144.      cout << "Ok.\n";
  145.      }
  146.  
  147. main(int argc, char **argv){
  148.     #ifndef IRIX
  149.     // This stuff is all just personal preference - you may want to change.
  150.     struct rlimit rl;
  151.     getrlimit(RLIMIT_STACK,&rl);
  152.     rl.rlim_cur=2500000;
  153.     setrlimit(RLIMIT_STACK,&rl);    // needs lots o' stack
  154.     getrlimit(RLIMIT_RSS,&rl);
  155.     rl.rlim_cur=1000000;
  156.     setrlimit(RLIMIT_RSS,&rl);        // be nice - ask for 1 meg. resident
  157.     getrlimit(RLIMIT_CORE,&rl);
  158.     rl.rlim_cur=1;
  159.     setrlimit(RLIMIT_CORE,&rl);        // cores will probably be too big    
  160.     #endif /* IRIX */
  161.  
  162.     // read in command line args and do whatever.
  163.     global_argv=argv;
  164.     global_argc=argc;
  165.  
  166.     while (global_argc>1) {
  167.         String s=nextarg();
  168.     if (s=="play")
  169.         playgame();
  170.     else if (s=="study")
  171.             study();
  172.     else if (s=="help") 
  173.         system("cat iku.help");
  174.     else if (s=="abort")
  175.         shouldabort=true;
  176.         else if (s=="evalfile")
  177.             evalfile=nextarg();
  178.         else if (s=="verify")
  179.             foreachfile(nextarg(),verify);
  180.         else if (s=="postscriptdir")
  181.             postscriptdir=nextarg();
  182.     else if (s=="nolearn")
  183.         dolearn=false;
  184.     else
  185.         fatal("Unrecognized command: "+s);
  186.     }
  187.     }
  188.  
  189. volatile void fatal(String errmsg) {
  190.     // Ticket straight to hell when program dies.
  191.     cout << errmsg << "\n";
  192.     if (shouldabort==true) {
  193.         cout << "Aborting...\n";
  194.     abort();
  195.     }
  196.     else {
  197.         cout << "Exiting...\n";
  198.     exit(1);
  199.     }
  200.     }
  201.  
  202. void playgame() {
  203.     // start up two opponents and play a game.  Never returns.
  204.     Opponent *bl=makeopponent(), *wh=makeopponent();
  205.     Board goban;
  206.     Move m;
  207.     dribble=nextarg();
  208.  
  209.     if (dribble!="nofile")
  210.         system((char*)("echo EVENT >"+dribble));
  211.     loop {
  212.     if (goban.turntoplay==black)
  213.         m=bl->getmove(goban);
  214.     else
  215.         m=wh->getmove(goban);
  216.  
  217.     if (goban.islegalmove(m))
  218.         goban.applymove(m);
  219.         else
  220.             fatal("Playgame saw bad move: "+m.str());
  221.         
  222.         if (dribble!="nofile") {
  223.             FILE *fp=fopen((char*)dribble,"a");
  224.             fprintf(fp,"%c %d ",(goban.turntoplay==blackstone)?'W':'B',goban.movenum-1);
  225.             fprintf(fp,"%s\n",(char *)m.str());
  226.             fclose(fp);
  227.             }
  228.     }
  229.     }
  230.  
  231. void study() {
  232.     // start opponent and make it study file(s) from command line.
  233.     optostudy=makeopponent();
  234.     String s=nextarg();
  235.     foreachfile(s,dostudy);
  236.     }
  237.  
  238. void getnum(int& what) {
  239.     // get a number from command line
  240.     String s=nextarg();
  241.     what=atoi(s);
  242.     if (what==0&&s!="0")
  243.         fatal("Needed a number, but got: "+s);
  244.     }
  245.  
  246. void takescore(int i, float f, int compress=1) {
  247.     // do something with the score, such a print it out.  If compress!=1,
  248.     // then take average.
  249.     if (dontprint)
  250.         return;
  251.     static int count=0;
  252.     static float sum=0.0;
  253.     count++;
  254.     sum+=f;
  255.     if (count==compress) {
  256.         cout << form("%d %4.3f\n",i,sum/count);
  257.         count=0;
  258.     sum=0.0;
  259.     }
  260.     }
  261.  
  262. int rotate(int a, int p) {
  263.     // used by hashpjw.
  264.     for (int i=0;i<(p>?(-p))%31;i++)
  265.         if (a&0x40000000)
  266.             a=(a<<1)|0x1;
  267.         else
  268.             a<<=1;
  269.     return a;
  270.     }
  271.  
  272. unsigned int hashpjw(const char* x) {
  273.     // My own hash function.  This seemed to work well; you may wish
  274.     // to substitute something else.  This is important for HashOpponents.
  275.     int h = 0;
  276.     while (*x != 0) 
  277.         h = rotate(h,h)^(*(x++));
  278.     return (unsigned) h;
  279.     }
  280.